package basickind

import (
	"gitee.com/zhongguo168a/gocodes/datax/convertx"
	"reflect"
	"strconv"
)

type Kind int

const (
	Invalid Kind = iota
	Bool         //1
	Int8
	Int16
	Int32
	Int64 //5
	Uint8
	Uint16
	Uint32
	Uint64
	Float32 //10
	Float64
	String
	Bytes //13
)

var kindNames = []string{
	Invalid: "invalid",
	Bool:    "bool",
	Int8:    "int8",
	Int16:   "int16",
	Int32:   "int32",
	Int64:   "int64",
	Uint8:   "uint8",
	Uint16:  "uint16",
	Uint32:  "uint32",
	Uint64:  "uint64",
	Float32: "float32",
	Float64: "float64",
	String:  "string",
	Bytes:   "bytes",
}

func (k Kind) String() string {
	if int(k) < len(kindNames) {
		return kindNames[k]
	}
	return "kind" + strconv.Itoa(int(k))
}
func NameToValue(name string) Kind {
	for key, val := range kindNames {
		if val == name {
			return Kind(key)
		}
	}
	return Invalid
}

func DefaultValue(typ Kind) interface{} {
	switch typ {
	case Bool:
		return false
	case Int8:
		return 0
	case Int16:
		return 0
	case Int32:
		return 0
	case Int64:
		return 0
	case Uint8:
		return uint(0)
	case Uint16:
		return uint(0)
	case Uint32:
		return uint(0)
	case Uint64:
		return uint(0)
	case Float32:
		return float64(0)
	case Float64:
		return float64(0)
	case String:
		return ""
	}
	return nil
}

func ConvertKindToStruct(kind Kind, val interface{}) (r interface{}) {
	switch kind {
	case Bool:
		r = convertx.AnyToBool(val)
	case Int8:
		r = convertx.AnyToInt(val)
	case Int16:
		r = convertx.AnyToInt(val)
	case Int32:
		r = convertx.AnyToInt(val)
	case Int64:
		r = convertx.AnyToInt(val)
	case Uint8:
		r = convertx.AnyToUint(val)
	case Uint16:
		r = convertx.AnyToUint(val)
	case Uint32:
		r = convertx.AnyToUint(val)
	case Uint64:
		r = convertx.AnyToUint(val)
	case Float32:
		r = convertx.AnyToFloat64(val)
	case Float64:
		r = convertx.AnyToFloat64(val)
	case String:
		r = convertx.AnyToString(val)
	}

	return
}

func NameToBasicKind(val string) (r Kind) {
	switch val {
	case "string":
		return String
	case "bool":
		return Bool
	case "int8":
		return Int8
	case "int16":
		return Int16
	case "int32":
		return Int32
	case "int64":
		return Int64
	case "int":
		return Int64
	case "uint8":
		return Uint8
	case "uint16":
		return Uint16
	case "uint32":
		return Uint32
	case "uint64":
		return Uint64
	case "uint":
		return Uint64
	case "float32":
		return Float32
	case "float64":
		return Float64
	}
	return Invalid
}

func GetBasicKind(val interface{}) (r Kind) {
	switch val.(type) {
	case string:
		return String
	case bool:
		return Bool
	case int8:
		return Int8
	case int16:
		return Int16
	case int32:
		return Int32
	case int64:
		return Int64
	case int:
		return Int64
	case uint8:
		return Uint8
	case uint16:
		return Uint16
	case uint32:
		return Uint32
	case uint64:
		return Uint64
	case uint:
		return Uint64
	case float32:
		return Float32
	case float64:
		return Float64
	}
	return Invalid
}

func ReflectKindToBasicKind(kind reflect.Kind) (r Kind) {
	switch kind {
	case reflect.String:
		return String
	case reflect.Bool:
		return Bool
	case reflect.Int8:
		return Int8
	case reflect.Int16:
		return Int16
	case reflect.Int32:
		return Int32
	case reflect.Int64:
		return Int64
	case reflect.Int:
		return Int64
	case reflect.Uint8:
		return Uint8
	case reflect.Uint16:
		return Uint16
	case reflect.Uint32:
		return Uint32
	case reflect.Uint64:
		return Uint64
	case reflect.Uint:
		return Uint64
	case reflect.Float32:
		return Float32
	case reflect.Float64:
		return Float64
	}
	return Invalid
}
